package com.brooks.demo.program.p1;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Semaphore;

/**
 * 面试题
 * 实现一个容器，提供两个方法，add,size
 * 写两个线程，线程1往容器里添加10个元素，线程2实现监控元素的个数，当个数到5时，线程2给出提示并结束
 *
 * semaphore 这个demo有问题,t1 release后 立马就acquire, t2并不一定能抢到
 * @Author mihutu
 * @Date 2020/10/20 11:11
 * @Version 1.0
 */
public class DemoSemaphore {
    /**
     * 这里使用同步容器来保证数据一致,否则会出现脏读的情况
     */
    volatile List list = Collections.synchronizedList(new LinkedList<>());

    public void add(Object o) {
        list.add(o);
    }

    public int size() {
        return list.size();
    }

    public static void main(String[] args) {
        DemoSemaphore v = new DemoSemaphore();
        Semaphore semaphore = new Semaphore(1);
        //添加元素的线程
        new Thread(() -> {
            System.out.println("t1已启动，准备添加元素");
            try {
                semaphore.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for (int i = 0; i < 10; i++) {
                v.add(new Object());
                System.out.println("添加了第" + i + "个元素");
                if(v.size()==5){
                    semaphore.release();
                    try {
                        semaphore.acquire();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            System.out.println("t1 结束");
        }, "t1").start();
        //监控数量的线程
        new Thread(() -> {
            System.out.println("t2监控已启动");
            try {
                semaphore.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("已经到第5个了，我结束了");
            semaphore.release();
        }, "t2").start();

    }
}
